package GUI;

import edu.uci.ics.jung.graph.Graph;
import edu.uci.ics.jung.graph.impl.SparseGraph;
import edu.uci.ics.jung.io.GraphMLFile;
import edu.uci.ics.jung.io.PajekNetReader;
import edu.uci.ics.jung.visualization.VisualizationViewer;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import java.io.File;
import javax.imageio.ImageIO;
import edu.uci.ics.jung.io.PajekNetWriter;

/**
 * GraphIO - zapis i wydruk grafu z dowolnego VisualizationViewer
 * @author Piotrek
 */
public class GraphIO implements Printable {

    private VisualizationViewer vv;

    /**
     * Konstruktor GraphIO
     * @param vv VisualizationViewer z rysowanym (narysowanym grafem)
     */
    public GraphIO(VisualizationViewer vv) {
        this.vv = vv;
    }

    /**
     * Zapis do pliku jpeg
     * @param file plik w którym zapisany zostanie graf
     * @param vv VisualizationViewer na którym wyświetlany jest graf
     */
    public static void writeJPEGImage(File file, VisualizationViewer vv) {
        int width = vv.getWidth();
        int height = vv.getHeight();

        BufferedImage bi = new BufferedImage(width, height,
                BufferedImage.TYPE_INT_RGB);
        Graphics2D graphics = bi.createGraphics();
        vv.paint(graphics);
        graphics.dispose();

        try {
            ImageIO.write(bi, "jpg", file);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * Drukowanie wizualizacji grafu.
     * @param graphics
     * @param pageFormat
     * @param pageIndex
     * @return Printable.NO_SUCH_PAGE lub Printable.PAGE_EXISTS {@link Printable}
     * @throws java.awt.print.PrinterException
     */
    public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException {
        if (pageIndex > 0) {
            return (Printable.NO_SUCH_PAGE);
        } else {
            java.awt.Graphics2D g2d = (java.awt.Graphics2D) graphics;
            vv.setDoubleBuffered(false);
            g2d.translate(pageFormat.getImageableX(), pageFormat.getImageableY());

            vv.paint(g2d);
            vv.setDoubleBuffered(true);

            return (Printable.PAGE_EXISTS);
        }
    }

    /**
     * Wydruk narysowanego grafu.
     * @param vv VisualizationViewer z narysowanym grafem
     */
    public static void print(VisualizationViewer vv) {
        PrinterJob printJob = PrinterJob.getPrinterJob();
        final GraphIO graphIO = new GraphIO(vv);
        printJob.setPrintable(graphIO);
        if (printJob.printDialog()) {
            try {
                printJob.print();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * Zapisuje graf na dysku w formacie PajekNet file.
     * @param graph graf
     * @param filename lokalizacja i nazwa pliku
     */
    public static void writeGraphPNF(Graph graph, String filename) {
        PajekNetWriter gml = new PajekNetWriter();
        edu.uci.ics.jung.graph.decorators.Indexer.getAndUpdateIndexer(graph);
        try {
            gml.save(graph, filename + "."+Utils.pnf);
        } catch (Exception e) {
            System.err.println("ERROR zapisu grafu do pliku.");
            e.printStackTrace();
        }
    }

    /**
     * Ładuje graf z PajekNet pliku.
     * @param filename położenie oraz pełna nazwa pliku
     * @return skonstruowany graf
     */
    public static Graph readGraphPNF(String filename) {
        PajekNetReader gml = new PajekNetReader();
        Graph graph;
        try {
            graph = gml.load(filename);
        } catch (Exception exception) {
            System.err.println("ERROR odczyt grafu z pliku.");
            return new SparseGraph();

        }
        edu.uci.ics.jung.graph.decorators.Indexer.getAndUpdateIndexer(graph);
        return graph;
    }

    /**
     * Zapisuje graf na dysku w formacie GraphML plik.
     * @param graph graf
     * @param filename lokalizacja i nazwa pliku
     */
    public static void writeGraphGML(Graph graph, String filename) {
        GraphMLFile gml = new GraphMLFile();
        edu.uci.ics.jung.graph.decorators.Indexer.getAndUpdateIndexer(graph);
        try {
            gml.save(graph, filename + "."+Utils.gml);
        } catch (Exception e) {
            System.err.println("ERROR zapisu grafu do pliku.");
            e.printStackTrace();
        }
    }

    /**
     * Ładuje graf z GraphML pliku.
     * @param filename położenie oraz pełna nazwa pliku
     * @return skonstruowany graf
     */
    public static Graph readGraphGML(String filename) {
        GraphMLFile gml = new GraphMLFile();
        Graph graph;
        try {
            graph = gml.load(filename);
        } catch (Exception e) {
            System.err.println("ERROR odczyt grafu z pliku.");
            e.printStackTrace();
            return new SparseGraph();

        }
        edu.uci.ics.jung.graph.decorators.Indexer.getAndUpdateIndexer(graph);
        return graph;
    }
}

